// -*- C++ -*-
/***************************************************************************
 *
 * vector - declarations for the Standard Library vector class
 *
 * $Id: vector 172106 2011-11-02 17:04:12Z statham $
 *
 ***************************************************************************
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 ***************************************************************************
 *
 * Copyright (c) 1994-2001 Rogue Wave Software, Inc.  All Rights Reserved.
 *
 * This computer software is owned by Rogue Wave Software, Inc. and is
 * protected by U.S. copyright laws and other laws and by international
 * treaties.  This computer software is furnished by Rogue Wave Software,
 * Inc. pursuant to a written license agreement and may be used, copied,
 * transmitted, and stored only in accordance with the terms of such
 * license and with the inclusion of the above copyright notice.  This
 * computer software or any other copies thereof may not be provided or
 * otherwise made available to any other person.
 *
 * U.S. Government Restricted Rights.  This computer software is provided
 * with Restricted Rights.  Use, duplication, or disclosure by the
 * Government is subject to restrictions as set forth in subparagraph (c)
 * (1) (ii) of The Rights in Technical Data and Computer Software clause
 * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
 * Commercial Computer Software--Restricted Rights at 48 CFR 52.227-19,
 * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
 * Flatiron Parkway, Boulder, Colorado 80301 USA.
 *
 **************************************************************************/

#ifndef _RWSTD_VECTOR_INCLUDED
#define _RWSTD_VECTOR_INCLUDED

#include <limits>
#include <memory>

#include <rw/_algobase.h>
#include <rw/_iterator.h>
#include <rw/_defs.h>
#include <rw/_dispatch.h>
#include <rw/_error.h>


_RWSTD_NAMESPACE_BEGIN (std)

template <class _TypeT,
          class _Allocator _RWSTD_COMPLEX_DEFAULT(allocator<_TypeT>) >
class vector : private _Allocator
{
public:

    typedef _TypeT                                     value_type;
    typedef _Allocator                                 allocator_type;
    typedef _TYPENAME allocator_type::size_type        size_type;
    typedef _TYPENAME allocator_type::difference_type  difference_type;
    typedef _TYPENAME allocator_type::reference        reference;
    typedef _TYPENAME allocator_type::const_reference  const_reference;
    typedef _TYPENAME allocator_type::pointer          pointer;
    typedef _TYPENAME allocator_type::const_pointer    const_pointer;


#ifndef _RWSTD_NO_DEBUG_ITER

    typedef _RW::__rw_debug_iter <vector, pointer, pointer>  iterator;
    
    typedef _RW::__rw_debug_iter <vector, const_pointer, pointer>
        const_iterator;

    iterator _C_make_iter (pointer __ptr) {
        return iterator (*this, __ptr);
    }

    const_iterator _C_make_iter (pointer __ptr) const {
        return const_iterator (*this, __ptr);
    }

#else   // if defined (_RWSTD_NO_DEBUG_ITER)

    typedef pointer         iterator;
    typedef const_pointer   const_iterator;

    iterator _C_make_iter (pointer __ptr) {
        return __ptr;
    }

    const_iterator _C_make_iter (const_pointer __ptr) const {
        return __ptr;
    }

#endif   // _RWSTD_NO_DEBUG_ITER

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC 
    typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
    typedef _STD::reverse_iterator<iterator>       reverse_iterator;
#else
    typedef _STD::reverse_iterator<const_iterator, 
      random_access_iterator_tag, value_type, 
      const_reference, const_pointer, difference_type>
      const_reverse_iterator;
    typedef _STD::reverse_iterator<iterator, 
      random_access_iterator_tag, value_type,
      reference, pointer, difference_type>
      reverse_iterator;
#endif

protected:
    typedef _RWSTD_ALLOC_TYPE (_Allocator, value_type) _C_value_alloc_type;
    pointer            _C_start;
    pointer            _C_finish;
    pointer            _C_end_of_storage;

    void _C_insert_aux (iterator, const_reference);
    
    void _C_insert_aux (iterator, size_type, const_reference);
    
#ifndef _RWSTD_NO_MEMBER_TEMPLATES

    template<class _InputIter>
    void _C_insert_aux (iterator __position, _InputIter __first,
                        _InputIter __last, _RW_is_not_integer) {
        _C_insert_aux2 (__position, __first, __last);
    }

    template<class _InputIter>
    void _C_insert_aux (iterator __position, _InputIter __first,
                        _InputIter __last, _RW_is_integer) {
        _C_insert_aux (__position, (size_type)__first, __last);
    }
    
    template<class _InputIter>
    void _C_insert_aux2 (iterator __position, _InputIter __first,
                         _InputIter __last);

    template <class _InputIter>
    void _C_insert_interval_dispatch (iterator __position,
                                      _InputIter __first, 
                                      _InputIter __last,
                                      forward_iterator_tag) {
        typedef _TYPENAME _RWdispatch<_InputIter>::_RWtype _RWtype;
        _C_insert_aux(__position, __first, __last, _RWtype());
    }
    
    template <class _InputIter>
    void _C_insert_interval_dispatch (iterator __position,
                                      _InputIter __first, 
                                      _InputIter __last,
                                      input_iterator_tag) { 
        while(__first != __last) { 
            __position = insert (__position,*__first); 
            ++__position;
            ++__first;
        }
    }

#else
    void _C_insert_aux2 (iterator, const_iterator, const_iterator);
#endif

    void _C_destroy (iterator __start, iterator __finish) {
        for ( ; __start != __finish; ++__start)
            _RWSTD_VALUE_ALLOC (_C_value_alloc_type, destroy (&*__start));
    }
    
    // 
    //  Allocate buffers and fill with __n values
    //
    void _C_initn(size_type __n, const_reference __value) {
        size_t __initial_capacity = 
            max (__n, (size_t)_RW::__rw_new_capacity(0,this));

        _C_start = _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                                      allocate(__initial_capacity,0));
        _TRY {
            uninitialized_fill_n(begin(), __n, __value,
                                 _RWSTD_VALUE_ALLOC_CAST (*this));
        }
        _CATCH (...) {
            _RWSTD_VALUE_ALLOC(_C_value_alloc_type, deallocate(_C_start,__n));
            _RETHROW;
        }
        _C_finish = _C_start + __n;
        _C_end_of_storage = _C_start + __initial_capacity;
    } 


public:

    _EXPLICIT vector (const _Allocator& __alloc = allocator_type ())
        : allocator_type (__alloc), _C_start (0), _C_finish (0),
          _C_end_of_storage (0){ }

    _EXPLICIT
    vector (size_type __n, const_reference __value = value_type (),
            const _Allocator& __alloc = allocator_type ())
        : allocator_type(__alloc), _C_start(0), _C_finish(0),
          _C_end_of_storage (0) {
        _C_initn (size_type (__n), __value);
    }

#ifndef _RWSTD_NO_MEMBER_TEMPLATES
    
    template<class _InputIter>
    void _C_init_aux (_InputIter __first, _InputIter __last,
                     _RW_is_not_integer) {
        if (__is_input_iterator (_RWSTD_ITERATOR_CATEGORY (_InputIter,
                                                           __first))) {
            copy(__first, __last, back_inserter(*this));
        }
        else {
            size_type __n = _DISTANCE (__first, __last, size_type);
            size_t __initial_capacity = 
                max (__n, (size_t)_RW::__rw_new_capacity(0,this));
            _C_start = _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                                          allocate(__initial_capacity,0));
            
            _TRY {
                uninitialized_copy(__first, __last, _C_start,
                                   _RWSTD_VALUE_ALLOC_CAST (*this));
            }
            _CATCH (...) {
                _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                                   deallocate(_C_start,__n));
                _RETHROW;
            }
            _C_finish = _C_start + __n;
            _C_end_of_storage = _C_start + __initial_capacity;
        }
    }

    template<class _InputIter>
    void _C_init_aux (_InputIter __first, _InputIter __last,
                      _RW_is_integer) {
        _C_initn((size_type)__first,__last);
    }

    template<class _InputIter>
    vector (_InputIter __first, _InputIter __last,
            const _Allocator& __alloc = allocator_type ())
      : allocator_type(__alloc), _C_start(0), _C_finish(0),
        _C_end_of_storage(0) {
        typedef _TYPENAME _RWdispatch<_InputIter>::_RWtype _RWtype;
        _C_init_aux(__first, __last, _RWtype());
    }
    
#else  // defined _RWSTD_NO_MEMBER_TEMPLATES

    vector (const_iterator __first, const_iterator __last,
            const _Allocator& __alloc = allocator_type ())
      : allocator_type(__alloc), _C_start(0), _C_finish(0),
        _C_end_of_storage(0) {
        size_type __n = _DISTANCE (__first, __last, size_type);
        size_t __initial_capacity = 
            max (__n, (size_t)_RW::__rw_new_capacity(0,this));
        _C_start = _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                                      allocate(__initial_capacity,0));
        
        _TRY {
            uninitialized_copy(__first, __last, _C_start,
                                 _RWSTD_VALUE_ALLOC_CAST (*this));
        }
        _CATCH (...) {
            _RWSTD_VALUE_ALLOC(_C_value_alloc_type, deallocate(_C_start,__n));
            _RETHROW;
        }
        _C_finish = _C_start + __n;
        _C_end_of_storage = _C_start + __initial_capacity;
    }
    
#endif // _RWSTD_NO_MEMBER_TEMPLATES

    vector (const vector &__x)
        : allocator_type (__x.get_allocator ()), _C_start(0), _C_finish(0),
          _C_end_of_storage(0) {

        size_t __initial_capacity = 
            max (__x.size(), (size_t)_RW::__rw_new_capacity(0,this));
        _C_start = _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                                      allocate(__initial_capacity,0));
        _TRY {
            uninitialized_copy(__x.begin(), __x.end(), begin(),
                                 _RWSTD_VALUE_ALLOC_CAST (*this));
        }
        _CATCH (...) {
            _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                               deallocate(_C_start,__x.size()));
            _RETHROW;
        }
        _C_finish = _C_start + __x.size();
        _C_end_of_storage = _C_start + __initial_capacity;
    }
    
    
    ~vector () { 
        _C_destroy(begin (), end ()); 
        _RWSTD_VALUE_ALLOC(_C_value_alloc_type, deallocate(_C_start,
                                              _C_end_of_storage - _C_start));
    }
    
    vector& operator= (const vector &__x);
    
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
    template<class _InputIter>
    void assign (_InputIter __first, _InputIter __last) {
        erase(begin(), end());
        typedef _TYPENAME _RWdispatch<_InputIter>::_RWtype _RWtype;
        _C_insert_aux(begin(), __first, __last, _RWtype());
    }
    
    void assign (size_type __n, const_reference __t) {
        erase(begin(), end()); insert(begin(), __n, __t);
    }
#else
    void assign (const_iterator __first, const_iterator __last) {
        erase(begin(), end()); insert(begin(), __first, __last);
    }
    //
    // Assign n copies of t to this vector.
    //
    void assign (size_type __n, const_reference __t) {
        erase(begin(), end()); insert(begin(), __n, __t);
    }

#endif // _RWSTD_NO_MEMBER_TEMPLATES

    allocator_type get_allocator() const {
        return *this;
    }
    
    //
    // Iterators.
    //
    iterator       begin ()       {
        return _C_make_iter (_C_start);
    }

    const_iterator begin () const {
        return _C_make_iter (_C_start);
    }

    iterator       end ()         {
        return _C_make_iter (_C_finish);
    }

    const_iterator end ()   const {
        return _C_make_iter (_C_finish);
    }
    
    reverse_iterator rbegin () { 
        reverse_iterator __tmp(end());
        return __tmp;
    }
    
    const_reverse_iterator rbegin () const { 
        const_reverse_iterator __tmp(end());
        return __tmp;
    }
    
    reverse_iterator rend () { 
        reverse_iterator __tmp(begin());
        return __tmp;
    }
    
    const_reverse_iterator rend () const { 
        const_reverse_iterator __tmp(begin());
        return __tmp;
    }

    size_type size ()     const {
        return size_type(end() - begin());
    }

    size_type max_size () const {
        return _RWSTD_VALUE_ALLOC(_C_value_alloc_type, max_size());
    }
    
    void resize (size_type __new_size, value_type __value = value_type ()) {
        if (__new_size > size())
            insert(end(), __new_size - size(), __value);
        else if (__new_size < size())
            erase(begin() + __new_size, end());
    }

    size_type capacity () const {
        return _C_end_of_storage - _C_start;
    }
    
    bool      empty ()    const {
        return begin() == end();
    }
    
    void reserve (size_type __n) {
        _RWSTD_REQUIRES (__n <= max_size (),
                         (_RWSTD_ERROR_LENGTH_ERROR,
                          _RWSTD_FUNC ("vector::reserve(size_type)"),
                          __n, max_size ()));

        if (capacity() < __n) {
            size_t __new_capacity = 
                max (__n, (size_t)_RW::__rw_new_capacity(size(),this));
            pointer __tmp =
                _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                                   allocate(__new_capacity,_C_start));

            _TRY {
                uninitialized_copy(begin(), end(), _C_make_iter (__tmp),
                                 _RWSTD_VALUE_ALLOC_CAST (*this));
            }
            _CATCH (...) {
                _RWSTD_VALUE_ALLOC(_C_value_alloc_type, deallocate(__tmp,__n));
                _RETHROW;
            }
            _C_destroy(begin (), end ());
            _RWSTD_VALUE_ALLOC(_C_value_alloc_type, 
                deallocate(_C_start, _C_end_of_storage - _C_start));
            _C_finish = __tmp + size();
            _C_start = __tmp;
            _C_end_of_storage = _C_start + __new_capacity;
        }
    }

    //
    // Element access.
    //
    reference       operator[] (size_type __n) {

#ifdef _RWSTD_BOUNDS_CHECKING

        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_OUT_OF_RANGE,
                          _RWSTD_FUNC ("vector::operator[](size_type)"),
                          __n, size ()));

#endif   // _RWSTD_BOUNDS_CHECKING

        return *(begin() + __n);

    }
  
    const_reference operator[] (size_type __n) const {

#ifdef _RWSTD_BOUNDS_CHECKING

        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_OUT_OF_RANGE,
                          _RWSTD_FUNC ("vector::operator[](size_type) const"),
                          __n, size ()));

#endif   // _RWSTD_BOUNDS_CHECKING

        return *(begin() + __n);
    }
  
    reference at (size_type __n) { 
        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_OUT_OF_RANGE,
                          _RWSTD_FUNC ("vector::at (size_type)"),
                          __n, size ()));
        return *(begin() + __n); 
    }
    
    const_reference at (size_type __n)  const  { 
        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_OUT_OF_RANGE,
                          _RWSTD_FUNC ("vector::at(size_type) const"),
                          __n, size ()));
        return *(begin() + __n); 
    }
    
    reference front () {
        return *begin();
    }
    
    const_reference front () const {
        return *begin();
    }
    
    reference back () {
        return *(end() - 1);
    }
    
    const_reference back () const {
        return *(end() - 1);
    }

    //
    // Modifiers.
    //
    void push_back (const_reference __x) {
        if (_C_finish != _C_end_of_storage) {
            ++_C_finish;
            _TRY {
                _RWSTD_VALUE_ALLOC (_C_value_alloc_type,
                                    construct (_C_finish - difference_type (1),
                                               __x));
            }
            _CATCH (...) {
                --_C_finish;
                _RETHROW;
            }
        }
        else
            _C_insert_aux(end(), __x);
    }
    
    void pop_back()
    {
        _RWSTD_VALUE_ALLOC(_C_value_alloc_type, destroy(_C_finish-1));
        --_C_finish; 
    }

    //
    // Insert x at __position.
    //
    iterator insert (iterator __position, const_reference __x) {
        size_type __n = __position - begin();
        if (_C_finish != _C_end_of_storage && __position == end()) {
            ++_C_finish;
            _TRY {
                _RWSTD_VALUE_ALLOC(_C_value_alloc_type,
                                   construct(_C_finish - 1, __x));
            }
            _CATCH (...) {
                --_C_finish;
                _RETHROW;
            }
        }
        else
            _C_insert_aux(__position, __x);
        return begin() + __n;
    }

#ifndef _RWSTD_NO_MEMBER_TEMPLATES

    template <class _InputIter>
    void insert (iterator __pos, _InputIter __first, _InputIter __last) {
        insert (__pos, __first, __last, _RWSTD_DISPATCH (_InputIter));
    }
    
    template <class _InputIter>
    void insert (iterator __pos, _InputIter __first, _InputIter __last,
                 _RWSTD_DISPATCH_INT (false)) {
        // unnamed arg is used for overload resolution
        // _RWSTD_COMPILE_ASSERT (sizeof (*__first));
        _C_insert_interval_dispatch  (__pos, __first, __last,
                                      _RWSTD_ITERATOR_CATEGORY (_InputIter,
                                                                __first));
    }

    void insert (iterator __pos, size_type __n, const_reference __val,
                 _RWSTD_DISPATCH_INT (true)) {
        // unnamed arg is used for overload resolution
        _C_insert_aux (__pos, __n, __val);
    }

    void insert (iterator __position, size_type __n, const_reference __value) {
        _C_insert_aux(__position,__n,__value);
    }
    
#else

    void insert (iterator __position, size_type __n, const_reference __x) {
        _C_insert_aux(__position,__n,__x);
    }
    
    void insert (iterator __position, const_iterator __first,
                 const_iterator __last) {
        _C_insert_aux2(__position, __first, __last);
    }
    
#endif // _RWSTD_NO_MEMBER_TEMPLATES

    iterator erase (iterator __position) {
        if (!empty ()) { 
            if (__position + 1 != end()) 
                copy(__position + 1, end(), __position);
            _RWSTD_VALUE_ALLOC(_C_value_alloc_type, destroy(_C_finish - 1));
            --_C_finish;
        }
        return __position;
    }

    iterator erase (iterator __first, iterator __last) {
        if (!empty ()) {
            iterator __i = copy (__last, end(), __first);
            iterator __tmp = end ();
            _C_destroy(__i, __tmp);
            _C_finish -= (__last - __first);
        }
        return __first;
    }

    void swap (vector& __x) {
        if((_C_value_alloc_type)*this==(_C_value_alloc_type)__x) {
            _STD::swap (_C_start, __x._C_start);
            _STD::swap (_C_finish, __x._C_finish);
            _STD::swap (_C_end_of_storage, __x._C_end_of_storage);
        }
        else {
            vector __v = *this;
            *this = __x;
            __x=__v;
        } 
    }
    
    void clear () {
        erase (begin (), end ());
    }

};

template <class _TypeT, class _Allocator>
inline bool operator== (const vector<_TypeT,_Allocator>& __x,
                        const vector<_TypeT,_Allocator>& __y)
{
    return __x.size() == __y.size()
        && equal(__x.begin(), __x.end(), __y.begin());
}

template <class _TypeT, class _Allocator>
inline bool operator< (const vector<_TypeT,_Allocator>& __x,
                       const vector<_TypeT,_Allocator>& __y)
{
    return lexicographical_compare(__x.begin(), __x.end(),
                                   __y.begin(), __y.end());
}

template <class _TypeT, class _Allocator>
inline bool operator!= (const vector<_TypeT,_Allocator>& __x,
                        const vector<_TypeT,_Allocator>& __y)
{
    return !(__x == __y);
}

template <class _TypeT, class _Allocator>
inline bool operator> (const vector<_TypeT,_Allocator>& __x,
                       const vector<_TypeT,_Allocator>& __y)
{
    return __y < __x;
}

template <class _TypeT, class _Allocator>
inline bool operator>= (const vector<_TypeT,_Allocator>& __x,
                        const vector<_TypeT,_Allocator>& __y)
{
    return !(__x < __y);
}

template <class _TypeT, class _Allocator>
inline bool operator<= (const vector<_TypeT,_Allocator>& __x,
                        const vector<_TypeT,_Allocator>& __y)
{
    return !(__y <  __x);
}

#ifndef _RWSTD_NO_PART_SPEC_OVERLOAD

template <class _TypeT, class _Allocator>
inline void swap(vector<_TypeT,_Allocator>& __a, vector<_TypeT,_Allocator>& __b)
{
    __a.swap(__b);
}

#endif   // _RWSTD_NO_PART_SPEC_OVERLOAD


#ifndef _RWSTD_NO_VECTOR_BOOL

#ifndef _RWSTD_NO_BOOL

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>

#else   // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC)

     // use a macro to mutate _Allocator into allocator<bool>
# define _Allocator allocator<bool>

_RWSTD_SPECIALIZED_CLASS

#endif  // _RWSTD_NO_CLASS_PARTIAL_SPEC

class _RWSTD_EXPORT vector<bool, _Allocator > : private _Allocator
{
    typedef _RWSTD_REBIND(_Allocator, unsigned int)       _C_value_alloc_type;

    typedef vector                                        _C_self;
public:

    typedef _Allocator                                    allocator_type;
    typedef bool                                          value_type;

    typedef _TYPENAME allocator_type::size_type           size_type;
    typedef _TYPENAME allocator_type::difference_type     difference_type;
    typedef _TYPENAME _C_value_alloc_type::pointer        pointer;
    typedef _TYPENAME _C_value_alloc_type::const_pointer  const_pointer;

    class iterator;
    class const_iterator;

    class reference {
        friend class iterator;
        friend class const_iterator;

    protected:

        unsigned int* _C_p;
        unsigned int _C_mask;
        reference (unsigned int* __x, unsigned int __y)
            : _C_p (__x), _C_mask (__y) { }
    public:

        reference () : _C_p(0), _C_mask(0) {}

        operator bool () const {
            return !!(*_C_p & _C_mask);
        }

        reference& operator= (bool __x) {
            if (__x)      
                *_C_p |= _C_mask;
            else
                *_C_p &= ~_C_mask;
            return *this;
        }

        reference& operator= (const reference& __x) {
            return *this = bool(__x);
        }

#ifndef _RWSTD_NO_EXT_VECTOR_BOOL_REF_OPS

      bool operator== (const reference& __x) const {
          return bool(*this) == bool(__x);
      }

      bool operator< (const reference& __x) const {
#ifndef _MSC_VER
          return bool(*this) < bool(__x);
#else
          return int(*this) < int(__x);
#endif
      }

        bool operator!= (const reference& __x) const {
            return !(*this == __x);
        }

        bool operator> (const reference& __x) const {
            return  __x < *this;
        }

        bool operator>= (const reference& __x) const {
            return !(*this < __x);
        }

        bool operator<= (const reference& __x) const {
            return !(*this > __x);
        }

#endif // _RWSTD_NO_EXT_VECTOR_BOOL_REF_OPS

        void flip () {
            *_C_p ^= _C_mask;
        }
    };
    
    typedef bool const_reference;

    // hacks working around bogus g++ 2.95.2 warnings coming out of
    // iterators below as well as what's probably an MSVC 6.0 bug
    typedef reference       _C_ref;
    typedef const_reference _C_const_ref;
    typedef difference_type _C_diff_t;

    class _C_iter {
        friend class iterator;
        friend class const_iterator;

    protected:

#if defined (__GNUG__) && __GNUG__ == 2 && __GNUG_MINOR__ < 96
    public:
#elif defined (_MSC_VER) && _MSC_VER <= 1300
        friend class vector<bool, _Allocator>;
#else
        friend class vector;
#endif
        unsigned int* _C_p;
        unsigned int  _C_offset;

        _C_iter (unsigned int* __x = 0, unsigned int __y = 0)
            : _C_p (__x), _C_offset (__y) { }

        void operator++ () {
            if (_C_offset++ == _RWSTD_WORD_BIT - 1) {
                _C_offset = 0; 
                ++_C_p;
            }
        }

        void operator-- () {
            if (_C_offset-- == 0) {
                _C_offset = _RWSTD_WORD_BIT - 1; 
                --_C_p;
            }
        }

        void operator+= (difference_type __i) {
            difference_type __n = __i + _C_offset;
            _C_p += __n / _RWSTD_WORD_BIT;
            __n = __n % _RWSTD_WORD_BIT;
            if (__n < 0) {
                _C_offset = _RWSTD_STATIC_CAST (unsigned int,
                                                __n + _RWSTD_WORD_BIT);
                --_C_p;
            }
            else
                _C_offset = _RWSTD_STATIC_CAST (unsigned int,__n);
        }

    public:

        bool operator== (const _C_iter& __x) const {
            return _C_p == __x._C_p && _C_offset == __x._C_offset;
        }

        bool operator< (const _C_iter& __x) const {
            return _C_p < __x._C_p ||
                (_C_p == __x._C_p && _C_offset < __x._C_offset);
        }

        bool operator!= (const _C_iter& __x) const {
            return !(*this == __x);
        }

        bool operator> (const _C_iter& __x) const {
            return __x < *this;
        }

        bool operator>= (const _C_iter& __x) const {
            return !(*this < __x);
        }

        bool operator<= (const _C_iter& __x) const {
            return !(*this > __x);
        }
    };
      
    class iterator
        : public _C_iter,
          public _STD::iterator<random_access_iterator_tag,
                                value_type, _C_diff_t,
                                pointer, _C_ref> {
    public:

        // bring names used in declarations below into scope
        // (dependent base members not visible without qualification)
        typedef _C_ref    reference;
        typedef _C_diff_t difference_type;

        iterator (unsigned int *__x = 0, unsigned int __y = 0)
            : _C_iter (__x, __y) { }

        reference operator* () const { 
            typedef reference _Reference;
            return _Reference (this->_C_p, 1U << this->_C_offset); 
        }

        iterator& operator++ () {
            return _C_iter::operator++(), *this;
        }

        iterator operator++ (int) {
            iterator __tmp = *this;
            ++*this;
            return __tmp;
        }

        iterator& operator-- () {
            return _C_iter::operator--(), *this;
        }

        iterator operator-- (int) {
            iterator __tmp = *this;
            --*this;
            return __tmp;
        }

        iterator& operator+= (difference_type __i) {
            return _C_iter::operator+= (__i), *this;
        }

        iterator& operator-= (difference_type __i) {
            *this += -__i;
            return *this;
        }

        iterator operator+ (difference_type __i) const {
            iterator __tmp = *this;
            return __tmp += __i;
        }

        iterator operator- (difference_type __i) const {
            iterator __tmp = *this;
            return __tmp -= __i;
        }

        difference_type operator- (iterator __x) const {
            return   _RWSTD_WORD_BIT * (this->_C_p - __x._C_p)
                   + this->_C_offset - __x._C_offset;
        }

        reference operator[] (difference_type __i) {
            return *(*this + __i);
        }
    };

    class const_iterator
        : public _C_iter,
          public _STD::iterator<random_access_iterator_tag,
                                value_type, _C_diff_t,
                                const_pointer, _C_const_ref> {
    public:

        // bring names used in declarations below into scope
        // (dependent base members not visible without qualification)
        typedef _C_const_ref const_reference;
        typedef _C_diff_t    difference_type;

        const_iterator (unsigned int *__x = 0, unsigned int __y = 0)
            : _C_iter (__x, __y) { }

        const_iterator (const _C_iter &__x)
            : _C_iter (__x._C_p, __x._C_offset) { }

        const_reference operator* () const {
            return _C_ref (this->_C_p, 1U << this->_C_offset);
        }

        const_iterator& operator++ () {
            return _C_iter::operator++(), *this;
        }

        const_iterator operator++ (int) {
            const_iterator __tmp = *this;
            ++*this;
            return __tmp;
        }

        const_iterator& operator-- () {
            return _C_iter::operator--(), *this;
        }

        const_iterator operator-- (int) {
            const_iterator __tmp = *this;
            --*this;
            return __tmp;
        }

        const_iterator& operator+= (difference_type __i) {
            return _C_iter::operator+= (__i), *this;
        }

        const_iterator& operator-= (difference_type __i) {
            return *this += -__i;
        }

        const_iterator
        operator+ (difference_type __i) const {
            return const_iterator (*this) += __i;
        }

        const_iterator operator- (difference_type __i) const {
            return const_iterator (*this) -= __i;
        }

        difference_type operator- (const_iterator __x) const {
            return   _RWSTD_WORD_BIT * (this->_C_p - __x._C_p)
                   + this->_C_offset - __x._C_offset;
        }

        const_reference operator[] (difference_type __i) { 
            return *(*this + __i); 
        }
    };

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC 

    typedef _STD::reverse_iterator<const_iterator> const_reverse_iterator;
    typedef _STD::reverse_iterator<iterator>       reverse_iterator;

#else

    typedef _STD::reverse_iterator<const_iterator, 
        random_access_iterator_tag, value_type, 
        const_reference, const_pointer, difference_type>
    const_reverse_iterator;

    typedef _STD::reverse_iterator<iterator, 
        random_access_iterator_tag, value_type,
        reference, pointer, difference_type>
    reverse_iterator;

#endif   // _RWSTD_NO_CLASS_PARTIAL_SPEC 

  private:
    //
    // These private functions are replicas of generic algorithms.
    //  We provide them here to avoid putting instantiations of 
    //  the generic algorithms into an archive or shared library.
    //  This gives you full flexibilty in deciding where you want
    //  to put particular instantiations of the generic 
    //  algorithms.
    //
  
    void _C_fill (iterator __first, iterator __last, const bool& __value) {
        while (__first != __last) *__first++ = __value;
    }

    void _C_fill_n (iterator __first, size_type __n, const bool& __value) {
        while (__n-- > 0) *__first++ = __value;
    }

#ifndef _RWSTD_NO_MEMBER_TEMPLATES

    template <class _Iterator>
    iterator _C_copy (_Iterator __first, _Iterator __last, iterator __res) {
        while (__first != __last)
            *__res++ = *__first++;
        return __res;
    }

    template <class _Iterator>
    iterator
    _C_copy_backward (_Iterator __first, _Iterator __last, iterator __res) {
        while (__first != __last) *--__res = *--__last;
        return __res;
    }

#else
    iterator
    _C_copy (const_iterator __first, const_iterator __last, iterator __res) {
        while (__first != __last)
            *__res++ = *__first++;
        return __res;
    }

    iterator _C_copy (const bool* __first, const bool* __last, iterator __res) {
        while (__first != __last)
            *__res++ = *__first++;
        return __res;
    }

    iterator _C_copy_backward (const_iterator __first, const_iterator __last,
                               iterator __res) {
        while (__first != __last)
            *--__res = *--__last;
        return __res;
    }

    iterator
    _C_copy_backward (const bool* __first, const bool* __last, iterator __res) {
        while (__first != __last)
            *--__res = *--__last;
        return __res;
    }

#endif

protected:

    iterator       _C_start;
    iterator       _C_finish;
    unsigned int * _C_end_of_storage;

    unsigned int* _C_bit_alloc (size_type __n) {
        return _C_value_alloc_type(*this).
            allocate ((__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT,
                      pointer(_C_start._C_p));
    }

    void _C_init (size_type __n) {
        unsigned int* __q = _C_bit_alloc(__n);
        _C_end_of_storage = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
        _C_start = iterator(__q, 0);
        _C_finish = _C_start + __n;
    }

    void _C_insert_aux (iterator, bool);

public:

    vector (const _Allocator&  __alloc = allocator_type ())
      : allocator_type (__alloc), _C_start(iterator()), _C_finish(iterator()), 
        _C_end_of_storage(0) { }

    _EXPLICIT vector (size_type __n, bool __value = bool(), 
       const _Allocator&  __alloc = allocator_type ())
      : allocator_type (__alloc), _C_end_of_storage(0) {
      _C_init(__n); 
      unsigned int * __first = _C_start._C_p;
      size_type __m = (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
      while (__m-- > 0) *__first++ = __value ? ~0 : 0;
    }

    vector (const _C_self &__x)
        : allocator_type (__x.get_allocator ()), _C_end_of_storage (0) {
        _C_init (__x.size ()); 
        _C_copy (__x.begin (), __x.end (), _C_start);
    }

#ifndef _RWSTD_NO_MEMBER_TEMPLATES
    template<class _InputIter>
    vector  (_InputIter __first, _InputIter __last)
      : _C_end_of_storage(0)
    {
      size_type __n = _DISTANCE (__first, __last, size_type);
      _C_init(__n); 
      _C_copy(__first, __last, _C_start);
    }
#else
    vector (const_iterator __first, const_iterator __last)
      : _C_end_of_storage(0)
    {
      size_type __n = _DISTANCE (__first, __last, size_type);
      _C_init(__n);
      _C_copy(__first, __last, _C_start);
    }
    vector (const bool* __first, const bool* __last)
      : _C_end_of_storage(0)
    {
      size_type __n = _DISTANCE (__first, __last, size_type);
      _C_init(__n);
      _C_copy(__first, __last, _C_start);
    }
#endif
  
    ~vector () {
      _C_value_alloc_type(*this).deallocate(_C_start._C_p,  
        _C_end_of_storage - _C_start._C_p); 
    }
    _C_self& operator= (const _C_self& __x)
    {
      if (&__x == this) return *this;
      if (__x.size() > capacity())
      {
        _C_value_alloc_type(*this).deallocate(_C_start._C_p,
          _C_end_of_storage - _C_start._C_p); 
        _C_init(__x.size());
      }
      _C_copy(__x.begin(), __x.end(), begin());
      _C_finish = begin() + __x.size();
      return *this;
    }
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
    template<class _InputIter>
    void assign (_InputIter __first, _InputIter __last)
    { erase(begin(), end()); insert(begin(), __first, __last); }
#else
    void assign (const_iterator __first, const_iterator __last)
    { erase(begin(), end()); insert(begin(), __first, __last); }
#endif

    void assign (size_type __n, const bool& __t = bool())
    { 
        erase(begin(), end()); insert(begin(), __n, __t);  
    }

    allocator_type get_allocator() const
    {
      return *this;
    }

    //
    // iterators
    //
    iterator       begin ()       { return _C_start; }
    const_iterator begin () const 
    { return const_iterator(_C_start._C_p,_C_start._C_offset); }
    iterator       end   ()       { return _C_finish; }
    const_iterator end   () const 
    { return const_iterator(_C_finish._C_p,_C_finish._C_offset); }

    reverse_iterator       rbegin () { return reverse_iterator(end()); }
    const_reverse_iterator rbegin () const
    { 
      return const_reverse_iterator(end()); 
    }
    reverse_iterator       rend () { return reverse_iterator(begin()); }
    const_reverse_iterator rend () const
    { 
      return const_reverse_iterator(begin()); 
    }

    //
    // capacity
    //
    size_type size     () const { return size_type(end() - begin());  }
    size_type max_size () const {
        return _C_value_alloc_type(*this).max_size();
    }
    void resize (size_type __new_size, bool __c = false);
    size_type capacity () const
    {
      return size_type(const_iterator(_C_end_of_storage, 0) - begin());
    }
    bool empty () const { return begin() == end(); }
    void reserve (size_type __n)
    {
        _RWSTD_REQUIRES (__n <= max_size (),
                         (_RWSTD_ERROR_LENGTH_ERROR,
                          _RWSTD_FUNC ("vector<bool>::reserve (size_type)"),
                          __n, max_size ()));

      if (capacity() < __n)
      {
        unsigned int* __q = _C_bit_alloc(__n);
        _C_finish = _C_copy(begin(), end(), iterator(__q, 0));
        _C_value_alloc_type(*this).deallocate(_C_start._C_p,
                                             _C_end_of_storage - _C_start._C_p);
        _C_start = iterator(__q, 0);
        _C_end_of_storage = __q + (__n + _RWSTD_WORD_BIT - 1)/_RWSTD_WORD_BIT;
      }
    }

    //
    // element access
    //
    reference       operator[] (size_type __n)       
    { 
#ifdef _RWSTD_BOUNDS_CHECKING

        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_LENGTH_ERROR,
                          _RWSTD_FUNC ("vector<bool>::[](size_type)"),
                          __n, size ()));

#endif   // _RWSTD_BOUNDS_CHECKING

      return *(begin() + __n); 
    }
    const_reference operator[] (size_type __n) const 
    { 
#ifdef _RWSTD_BOUNDS_CHECKING

        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_LENGTH_ERROR,
                          _RWSTD_FUNC ("vector<bool>::[](size_type)"),
                          __n, size ()));

#endif   // _RWSTD_BOUNDS_CHECKING

      return *(begin() + __n); 
    }
    reference       at (size_type __n)               
    { 
        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_LENGTH_ERROR,
                          _RWSTD_FUNC ("vector<bool>::at(size_type)"),
                          __n, size ()));
      return *(begin() + __n); 
    }
    const_reference at (size_type __n)   const 
    {
        _RWSTD_REQUIRES (__n < size (),
                         (_RWSTD_ERROR_LENGTH_ERROR,
                          _RWSTD_FUNC ("vector<bool>::at(size_type) const"),
                          __n, size ()));

      return *(begin() + __n); 
    }
    reference       front ()       { return *begin();     }
    const_reference front () const { return *begin();     }
    reference       back  ()       { return *(end() - 1); }
    const_reference back  () const { return *(end() - 1); }
    
    //
    // modifiers
    //
    void push_back (const bool& __x)
    {
        if (_C_finish._C_p != _C_end_of_storage) {
            ++_C_finish;
            *(_C_finish-1) = __x;
        }
        else
            _C_insert_aux(end(), __x);
    }
    void pop_back () { --_C_finish; }

    iterator insert (iterator __position, const bool& __x = bool())
    {
      size_type __n = __position - begin();
      if (_C_finish._C_p != _C_end_of_storage && __position == end()) {
          ++_C_finish;
          *(_C_finish-1) = __x;
      }
      else
        _C_insert_aux(__position, __x);
      return begin() + __n;
    }
    void insert (iterator __position, size_type __n, const bool& __x);

#ifndef _RWSTD_NO_MEMBER_TEMPLATES
    template<class _InputIter>
    void insert (iterator __position, _InputIter __first,
                 _InputIter __last);
#else
    void insert (iterator __position, const_iterator __first, 
                 const_iterator __last);
#endif

    iterator erase (iterator __position)
    {
      if (!(__position + 1 == end()))
        _C_copy(__position + 1, end(), __position);
      --_C_finish;
      return __position;
    }
    iterator erase(iterator __first, iterator __last)
    {
      _C_finish = _C_copy(__last, end(), __first);
      return __first;
    }
    void swap (_C_self& __x)
    {
      if((_C_value_alloc_type)*this == (_C_value_alloc_type)__x)
      {
        _STD::swap (_C_start,          __x._C_start);
        _STD::swap (_C_finish,         __x._C_finish);
        _STD::swap (_C_end_of_storage, __x._C_end_of_storage);
      }
      else
      {
        _C_self _x = *this;
        *this = __x;
        __x=_x;
      } 
    }
    static void swap(reference __x, reference __y);
    void flip ();
    void clear()
    {
      erase(begin(),end());
    }

  };
  
#ifndef _RWSTD_NO_FUNC_PARTIAL_SPEC

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>
#endif
  inline bool operator== (const vector<bool,_Allocator >& __x, 
                          const vector<bool,_Allocator >& __y)
  {
    if (__x.size() == __y.size())
    {
        _TYPENAME vector<bool,_Allocator >::const_iterator
        first1 = __x.begin(), 
        last1  = __x.end(),
        first2 = __y.begin();
            
      while (first1 != last1 && *first1 == *first2)
      {
        ++first1;
        ++first2;
      }
      return first1 == last1;
    }
    return false;
  }

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>
#endif
  inline bool operator< (const vector<bool,_Allocator >& __x, 
                         const vector<bool,_Allocator >& __y)
  {
    _TYPENAME vector<bool,_Allocator >::const_iterator
        first1 = __x.begin(), 
        last1  = __x.end(),
        first2 = __y.begin(),
        last2  = __y.end();

    while (first1 != last1 && first2 != last2)
    {
      if ((int)*first1 < (int)*first2)     return true;
      if ((int)*first2++ < (int)*first1++) return false;
    }
    return first1 == last1 && first2 != last2;
  }
#else

_RWSTD_SPECIALIZED_FUNCTION
  inline bool operator== (const vector<bool,allocator<bool> >& __x, 
                          const vector<bool,allocator<bool> >& __y)
  {
    if (__x.size() == __y.size())
    {
        vector<bool,allocator<bool> >::const_iterator
        first1 = __x.begin(), 
        last1  = __x.end(),
        first2 = __y.begin();
            
      while (first1 != last1 && *first1 == *first2)
      {
        ++first1;
        ++first2;
      }
      return first1 == last1;
    }
    return false;
  }

_RWSTD_SPECIALIZED_FUNCTION
  inline bool operator< (const vector<bool,allocator<bool> >& __x, 
                         const vector<bool,allocator<bool> >& __y)
  {
    vector<bool,allocator<bool> >::const_iterator
        first1 = __x.begin(), 
        last1  = __x.end(),
        first2 = __y.begin(),
        last2  = __y.end();

    while (first1 != last1 && first2 != last2)
    {
      if ((int)*first1 < (int)*first2)     return true;
      if ((int)*first2++ < (int)*first1++) return false;
    }
    return first1 == last1 && first2 != last2;
  }
#endif

#ifndef _RWSTD_NO_FUNC_PARTIAL_SPEC

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>
#endif
  inline bool operator!= (const vector<bool,_Allocator >& __x, 
                          const vector<bool,_Allocator >& __y)
  {
    return !(__x == __y);
  }

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>
#endif
  inline bool operator> (const vector<bool,_Allocator >& __x, 
                         const vector<bool,_Allocator >& __y)
  {
    return __y < __x;
  }

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>
#endif
  inline bool operator>= (const vector<bool,_Allocator >& __x, 
                          const vector<bool,_Allocator >& __y)
  {
    return !(__x < __y);
  }

#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>
#endif
  inline bool operator<= (const vector<bool,_Allocator >& __x, 
                          const vector<bool,_Allocator >& __y)
  {
    return !(__y <  __x);
  }

#ifndef _RWSTD_NO_PART_SPEC_OVERLOAD
#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
  template <class _Allocator>
#endif
  inline void swap(vector<bool,_Allocator >& __a, vector<bool,_Allocator >& __b)
  {
    __a.swap(__b);
  }
#endif

#else //_RWSTD_NO_FUNC_PART_SPEC

_RWSTD_SPECIALIZED_FUNCTION
  inline bool operator!= (const vector<bool,allocator<bool> >& __x, 
                          const vector<bool,allocator<bool> >& __y)
  {
    return !(__x == __y);
  }

_RWSTD_SPECIALIZED_FUNCTION
  inline bool operator> (const vector<bool,allocator<bool> >& __x, 
                         const vector<bool,allocator<bool> >& __y)
  {
    return __y < __x;
  }

_RWSTD_SPECIALIZED_FUNCTION
  inline bool operator>= (const vector<bool,allocator<bool> >& __x, 
                          const vector<bool,allocator<bool> >& __y)
  {
    return !(__x < __y);
  }

_RWSTD_SPECIALIZED_FUNCTION
  inline bool operator<= (const vector<bool,allocator<bool> >& __x, 
                          const vector<bool,allocator<bool> >& __y)
  {
    return !(__y <  __x);
  }

_RWSTD_SPECIALIZED_FUNCTION
inline void swap (vector<bool, allocator<bool> >& __a,
                  vector<bool, allocator<bool> >& __b)
  {
    __a.swap(__b);
  }

#endif

#undef _Allocator 

#endif   // _RWSTD_NO_BOOL

#endif   // _RWSTD_NO_VECTOR_BOOL

_RWSTD_NAMESPACE_END   // std

#if defined (_RWSTD_COMPILE_INSTANTIATE)
#  include <vector.cc>
#endif


#ifndef _RWSTD_NO_STL_SPECIALIZATION
#include "vector_spec.h"
#endif   // _RWSTD_NO_STL_SPECIALIZATION


#endif   // _RWSTD_VECTOR_INCLUDED

